package com.woniu108.product.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu108.carService.commons.log.AdminHistoryLog;
import com.woniu108.carService.commos.dto.AddressInfoDto;
import com.woniu108.carService.commos.dto.ScoreStoreDto;
import com.woniu108.carService.commos.dto.UserInfoDto;
import com.woniu108.carService.commos.exception.WoniuException;
import com.woniu108.carService.commos.model.Result;
import com.woniu108.carService.commos.util.*;
import com.woniu108.order.model.form.AddOrderScoreForm;
import com.woniu108.product.client.ExtraClient;
import com.woniu108.product.client.OrderClient;
import com.woniu108.product.client.PersonClient;
import com.woniu108.product.client.ValueAddedClient;
import com.woniu108.product.form.*;
import com.woniu108.product.param.BuyScoreProductParam;
import com.woniu108.valueAdded.form.AddScoreBuyLogForm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.woniu108.product.model.ScoreStore;
import com.woniu108.product.param.AddScoreProductParam;
import com.woniu108.product.param.ChangeScoreProductInfoParam;
import com.woniu108.product.param.ScoreProductListParam;
import com.woniu108.product.service.ScoreStoreService;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * <p>
 * 积分商城表 前端控制器
 * </p>
 *
 * @author yanxi
 * @since 2024-05-23
 */
@RestController
@RequestMapping("/scoreStore")
@Api(tags = "积分商城接口")
public class ScoreStoreController {

    @Resource
    private ScoreStoreService scoreStoreService;
    @Resource
    private OSSUtil ossUtil;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private ExtraClient extraClient;
    @Resource
    private PersonClient personClient;
    @Resource
    private ValueAddedClient valueAddedClient;
    @Resource
    private OrderClient orderClient;

    public String getUserId(String token){
        String refreshToken=redisUtil.getString(token);
        String userId= JWTUtil.parseUserToken(refreshToken).get("userId").toString();
        return userId;
    }
    /**
     * 筛选展示积分商品列表
     * @param form 积分商品筛选条件
     * @return Page<ScoreStoreDto> 单页积分商品信息
     */
    @PostMapping("/scoreProductList.c")
    @ApiOperation("筛选展示积分商品列表")
    public Result<Page<ScoreStoreDto>> scoreProductList(@RequestBody ScoreProductListForm form){
        ScoreProductListParam param = BeanUtil.toBean(form, ScoreProductListParam.class);
        Page<ScoreStoreDto> page=scoreStoreService.scoreProductList(param);
        return Result.newPageInstance(ScoreStoreDto.class).setData(page);
    }

    /**
     *
     * @param form
     * @return
     * @throws Exception
     */
    @PostMapping("/addScoreProduct.api")
    @ApiOperation("新增积分商品")@AdminHistoryLog
    public Result addScoreProduct(AddScoreProductForm form)throws Exception{
        AddScoreProductParam param=BeanUtil.toBean(form,AddScoreProductParam.class);
        //先判断文件是否为图片类型
        if (form.getPPicture()!=null&&!FileUtil.isImageFile(form.getPPicture().getInputStream())) {
            throw new WoniuException("上传文件类型错误，请上传图片", 10001);
        }else if(form.getPPicture()!=null){
            String oldName = form.getPPicture().getOriginalFilename();
            String suffix = oldName.substring(oldName.lastIndexOf("."));//取文件后缀
            String fileName = UUID.randomUUID().toString();//生成新的图片名称
            String filePath = ossUtil.uploadFile(form.getPPicture().getInputStream(), fileName + suffix, "class108");
            param.setPPicture(filePath);
        }
        param.setScoreProductState(StaticData.PRODUCT_INFO_STATE_NORMAL);
        String details = JSONUtil.toJsonStr(form.getPDetails());
        param.setPDetails(details);
        param.setCreateTime(LocalDateTime.now());
        ScoreStore scoreStore = BeanUtil.toBean(param, ScoreStore.class);
        scoreStoreService.save(scoreStore);
        return Result.getResult().setMsg("新增积分商品成功");
    }

    /**
     * 下架积分商品
     * @param scoreProductId 积分商品ID
     * @return result 是否正常访问接口结果
     */
    @GetMapping("/disabledScoreProduct.api")
    @ApiOperation("下架积分商品")@AdminHistoryLog
    @ApiImplicitParam(name = "scoreProductId",value ="积分商品ID" )
    public Result disabledScoreProduct(Integer scoreProductId){
        ScoreStore scoreStore = scoreStoreService.getById(scoreProductId);
        if(ObjectUtil.isEmpty(scoreStore)||scoreStore.getScoreProductState()!=StaticData.PRODUCT_TYPE_STATE_NORMAL){
            throw new WoniuException("商品不存在或状态异常",10001);
        }
        scoreStore.setScoreProductState(StaticData.PRODUCT_INFO_STATE_BAN);
        scoreStoreService.updateById(scoreStore);
        return Result.getResult().setMsg("下架积分商品成功");
    }

    /**
     * 上架积分商品(可上架指定商品数量;也可只调整状态，此时scoreProductNum=0)
     * @param scoreProductId 积分商品ID
     * @return result 是否正常访问接口结果
     */
    @GetMapping("/ableScoreProduct.api")
    @ApiOperation("上架积分商品")@AdminHistoryLog
    @ApiImplicitParams({
            @ApiImplicitParam(name = "scoreProductId",value ="积分商品ID" ),
            @ApiImplicitParam(name = "scoreProductNum",value ="上架积分商品数量" )
    })
    public Result ableScoreProduct(Integer scoreProductId,Integer scoreProductNum){
        ScoreStore scoreStore = scoreStoreService.getById(scoreProductId);
        if(ObjectUtil.isEmpty(scoreStore)||scoreStore.getScoreProductState()!=StaticData.PRODUCT_TYPE_STATE_BAN){
            throw new WoniuException("商品不存在或状态异常",10001);
        }
        if(scoreProductNum!=0) scoreStore.setScoreProductNum(scoreStore.getScoreProductNum()+scoreProductNum);
        scoreStore.setScoreProductState(StaticData.PRODUCT_INFO_STATE_NORMAL);
        scoreStoreService.updateById(scoreStore);
        return Result.getResult().setMsg("上架积分商品成功");
    }

    /**
     * 删除积分商品
     * @param scoreProductId 积分商品ID
     * @return result 是否正常访问接口结果
     */
    @GetMapping("/deleteScoreProduct.api")
    @ApiOperation("删除积分商品")@AdminHistoryLog
    @ApiImplicitParam(name = "scoreProductId",value ="积分商品ID" )
    public Result deleteScoreProduct(Integer scoreProductId){
        ScoreStore scoreStore = scoreStoreService.getById(scoreProductId);
        if(ObjectUtil.isEmpty(scoreStore)||scoreStore.getScoreProductState()==StaticData.PRODUCT_TYPE_STATE_DELETE){
            throw new WoniuException("商品不存在或状态异常",10001);
        }
        scoreStore.setScoreProductState(StaticData.PRODUCT_INFO_STATE_DELETE);
        scoreStoreService.updateById(scoreStore);
        //删除商品图片
        ossUtil.deleteFile("aliyunfyl", cn.hutool.core.io.FileUtil.getName(scoreStore.getPPicture()));
        return Result.getResult().setMsg("删除积分商品成功");
    }

    /**
     * 修改积分商品信息
     * @param form 修改积分商品信息详情
     * @return result 是否正常访问接口结果
     */
    @PostMapping("/changeScoreProductInfo.api")
    @ApiOperation("修改积分商品信息")@AdminHistoryLog
    public Result changeScoreProductInfo(@RequestBody ChangeScoreProductInfoForm form){
        ChangeScoreProductInfoParam param = BeanUtil.toBean(form, ChangeScoreProductInfoParam.class);
        if(form.getPDetails()!=null||form.getPDetails().size()!=0) {
            String details = JSONUtil.toJsonStr(form.getPDetails());
            param.setPDetails(details);
        }
        ScoreStore scoreStore = scoreStoreService.getById(param.getScoreProductId());
        if(param.getScorePrice()!=null)  scoreStore.setScorePrice(param.getScorePrice());
        if(param.getScoreProductName()!=null) scoreStore.setScoreProductName(param.getScoreProductName());
        if(param.getPDetails()!=null) scoreStore.setPDetails(param.getPDetails());
        scoreStoreService.updateById(scoreStore);
        return Result.getResult().setMsg("修改积分商品信息成功");
    }

    /**
     *更改积分商品图片
     * @param form 修改积分商品图片数据
     * @return result 是否正常访问接口结果
     */
    @PostMapping("/changeScoreProductImage.api")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file",value ="更新的图片文件" ),
            @ApiImplicitParam(name = "scoreProductId",value ="积分商品ID" )
    })
    @ApiOperation("更改积分商品图片")@AdminHistoryLog
    public Result changeScoreProductImage(ChangeScoreProductImageForm form) throws Exception{
        MultipartFile file = form.getFile();
        Integer scoreProductId = form.getScoreProductId();
        if(!FileUtil.isImageFile(file.getInputStream())){
            throw new Exception("上传文件类型错误，请上传图片");
        }
        ScoreStore scoreStore = scoreStoreService.getById(scoreProductId);
        if(ObjectUtil.isEmpty(scoreStore)||scoreStore.getScoreProductState()==StaticData.PRODUCT_TYPE_STATE_DELETE){
            throw new WoniuException("积分商品状态异常或不存在",10001);
        }
        String oldName=file.getOriginalFilename();
        String suffix=oldName.substring(oldName.lastIndexOf("."));//取文件后缀
        String fileName= UUID.randomUUID().toString();//生成新的图片名称
        String filePath= ossUtil.uploadFile(file.getInputStream(),fileName+suffix,"aliyunfyl");
        //删除商品图片
        ossUtil.deleteFile("aliyunfyl", cn.hutool.core.io.FileUtil.getName(scoreStore.getPPicture()));
        scoreStore.setPPicture(filePath);
        scoreStoreService.updateById(scoreStore);
        return Result.getResult().setMsg("修改商品图片成功");
    }


    /**
     * 兑换积分商品
     * @param token
     * @param form 兑换积分商品信息(种类，数量)
     * @return result 是否正常访问接口结果
     */
    @PostMapping("/bugScoreProduct")
    @Transactional
    @ApiOperation("兑换积分商品")
    public Result bugScoreProduct(@RequestHeader String token, @RequestBody BuyScoreProductForm form){
        BuyScoreProductParam param = BeanUtil.toBean(form, BuyScoreProductParam.class);
        String userId = this.getUserId(token);
        Integer scoreProductId = param.getScoreProductId();
        ScoreStore scoreStore = scoreStoreService.getById(scoreProductId);
        if(ObjectUtil.isEmpty(scoreStore)) throw new WoniuException("商品信息不存在",10001);
        if(scoreStore.getScoreProductState()!=StaticData.PRODUCT_INFO_STATE_NORMAL) throw new WoniuException("商品状态异常",10001);
        if(scoreStore.getScoreProductNum()<param.getNumber()) throw new WoniuException("可兑换数量不足",10001);
        //获取地址信息并判断
        Result<AddressInfoDto> result = extraClient.AddressInfoById(param.getAddressId());
        if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
        AddressInfoDto addressInfoDto = result.getData();
        //获取用户信息并判断
        Result<UserInfoDto> result1 = personClient.getByUserId(userId);
        if(result1.getCode()!=200) throw new WoniuException(result1.getMsg(),result1.getCode());
        UserInfoDto userInfoDto = result1.getData();
        //进行积分增减
        Integer totalScore=scoreStore.getScorePrice().intValue() * param.getNumber();
        Result<Integer> result2 = personClient.reduceUserScore(userId, totalScore, StaticData.SCORE_SHOPPING);
        if(result2.getCode()!=200) throw new WoniuException(result2.getMsg(),result2.getCode());
        //形成积分订单
        AddOrderScoreForm scoreForm = new AddOrderScoreForm();
        scoreForm.setScoreProductId(param.getScoreProductId());
        scoreForm.setTotalScore(BigDecimal.valueOf(totalScore));
        scoreForm.setAddressId(addressInfoDto.getAddressId());
        scoreForm.setUserId(userId);
        Result result4 = orderClient.addOrderScore(scoreForm);
        if(result4.getCode()!=200) throw new WoniuException(result4.getMsg(),result4.getCode());
        //加入用户的积分兑换记录中
        AddScoreBuyLogForm logForm = new AddScoreBuyLogForm();
        logForm.setScoreProductId(scoreProductId);
        logForm.setUserId(userId);
        logForm.setBuyNum(param.getNumber());
        logForm.setTotalScore(BigDecimal.valueOf(totalScore));
        Result result3 = valueAddedClient.addScoreBuyLog(logForm);
        if(result3.getCode()!=200) throw new WoniuException(result3.getMsg(),result3.getCode());
        return Result.getResult().setMsg("兑换积分商品成功");
    }
}

